<?php
    defined('M2_MICRO') or die('Direct Access to this location is not allowed.');

    /**
      * Import Model class for perform import operations
      * @name $importModel
      * @package M2 Micro Framework
      * @subpackage Modules
      * @author Alexander Chaika
      */
    class ImportModel extends Model {
        
        /**
          * @desc Import XML data to EA table
          * @param array $options options to exec
          * @return int|bool $result count of imported objects
          */
        public function importFromXML($options) {
            // get unique ids for previous imported objects from feed
            $this->database->query("SELECT `uid` FROM `#__estateagent` WHERE `feed` = '".$options['xslt-shema']."'");
            $exist = $this->database->getArray();
            
            // conver XML to objects
            $result = $this->normalize($options);
            
            // create update & insert queries
            $count = $update_count = $insert_count = $skipped = 0;
            $query = ''; $imported = array();
            $is_update = false;
            foreach($result as $item) {
                // check non relevant objects
                if (!empty($item->price) && !empty($item->street)) {
                    // check object existance
                    $is_update = (is_array($exist) && in_array($item->uid, $exist));
                    if ($is_update) {
                        $vars = get_object_vars($item);
                        $update = array();
                        foreach($vars as $field => $value) {
                            $update[] = "`" . $field . "` = '" . $this->database->getEscaped($value) . "'";
                        }
                        $query = "UPDATE `#__estateagent` 
                            SET ".implode(",", $update)." 
                            WHERE `uid` LIKE '".$item->uid."';";
                    } else {
                        $vars = get_object_vars($item);
                        $vars = array_map($this->database->getEscapeFunctionName(), $vars);
                        $query = "INSERT INTO `#__estateagent` 
                            (`".implode("`,`", array_keys($vars))."`) 
                            VALUES ('".implode("','", $vars)."');";
                    }

                    // update or add to DB records
                    $this->database->query($query);
                    if ($this->database->getResult() >= 0) {
                        if ($is_update){
                            $update_count++;
                        } else {
                            $insert_count++;
                        }
                    } else {
                        $errors[] = $this->getLastFromStack();
                    }
                    $count++;

                    // add uid for delete process
                    $imported[] = $item->uid;
                } else {
                    $skipped++;
                }
            }
            
            // delete non exist records
            if (is_array($exist) && is_array($imported)) {
                $not_exist = array_diff($exist, $imported);
                if (count($not_exist) > 0) {
                    $this->database->query("UPDATE `#__estateagent` SET `published` = 0 WHERE `uid` IN ('".implode("','", $not_exist)."')");
                }
            }
            
            // compile output
            $options['result'] = array(
                'updated'  => $update_count, 
                'inserted' => $insert_count, 
                'deleted'  => count($not_exist),
                'skipped'  => $skipped,
                'all'      => $count,
                'errors'   => $errors
            );
            return $options;
        }
        
        /**
          * @desc Convert XML to objects array
          * @param string $xml
          * @param bool $add_coords OPTIONAL use where you wish add yamap coords to object
          * @return array $objects
          */
        private function normalize($options, $add_coords = true) {
            // convert to simple XML object
            $xml = simplexml_load_string($options['data']);
            
            // add data to empty fields
            $result = array();
            foreach($xml->record as $item) {
                // create new record
                $record = new stdClass();
                
                // get XML attributes and add to record
                $vars = get_object_vars($item);
                foreach($vars as $field => $value) {
                    if (!empty($value)) {
                        $record->$field = iconv('utf-8', 'windows-1251', $value);
                    }
                }

                // get coords
                if ($add_coords) {
                    $address = $record->country . ', ' . $record->town . ', '
                             . ($record->locstate > 0 ? $record->locstate.'+район,' : '')
                             . ($record->street)
                             . ($record->streetnr > 0 ? ','.$record->streetnr : '');
                    $coords = $this->getCoords($address);
                    $record->map_x = (float)$coords[0];
                    $record->map_y = (float)$coords[1];
                }
                
                // add feed name
                $record->feed = $options['xslt-shema'];
                
                // add record to set
                $result[] = $record;
            }
            
            return $result;
        }
    }
?>